Add gtk_selection_model_[un]select_callback
authorMatthias Clasen <mclasen@redhat.com>
Fri, 5 Jun 2020 01:33:44 +0000 (21:33 -0400)
committerMatthias Clasen <mclasen@redhat.com>
Fri, 5 Jun 2020 02:28:54 +0000 (22:28 -0400)
Add a methods to add or remove a whole set
(specified via a query-range style callback).

gtk/gtkmultiselection.c
gtk/gtkselectionmodel.c
gtk/gtkselectionmodel.h

index f8ed44c2d421d97cd083f3cceb36d7d8f55c1886..a0ffb92feee2fa09f42d6b3a950c527be1b4f602 100644 (file)
@@ -167,6 +167,61 @@ gtk_multi_selection_unselect_all (GtkSelectionModel *model)
   return gtk_multi_selection_unselect_range (model, 0, g_list_model_get_n_items (G_LIST_MODEL (model)));
 }
 
+static gboolean
+gtk_multi_selection_add_or_remove (GtkSelectionModel    *model,
+                                   gboolean              add,
+                                   GtkSelectionCallback  callback,
+                                   gpointer              data)
+{
+  GtkMultiSelection *self = GTK_MULTI_SELECTION (model);
+  guint pos, start, n;
+  gboolean in;
+  guint min, max;
+
+  min = G_MAXUINT;
+  max = 0;
+
+  pos = 0;
+  do
+    {
+      callback (pos, &start, &n, &in, data);
+      if (in)
+        {
+          if (start < min)
+            min = start;
+          if (start + n - 1 > max)
+            max = start + n - 1;
+
+          if (add)
+            gtk_set_add_range (self->selected, start, n);
+          else
+            gtk_set_remove_range (self->selected, start, n);
+        }
+      pos = start + n;
+    }
+  while (n > 0);
+
+  gtk_selection_model_selection_changed (model, min, max - min + 1);
+
+  return TRUE;
+}
+
+static gboolean
+gtk_multi_selection_select_callback (GtkSelectionModel    *model,
+                                     GtkSelectionCallback  callback,
+                                     gpointer              data)
+{
+  return gtk_multi_selection_add_or_remove (model, TRUE, callback, data);
+}
+
+static gboolean
+gtk_multi_selection_unselect_callback (GtkSelectionModel    *model,
+                                       GtkSelectionCallback  callback,
+                                       gpointer              data)
+{
+  return gtk_multi_selection_add_or_remove (model, FALSE, callback, data);
+}
+
 static void
 gtk_multi_selection_query_range (GtkSelectionModel *model,
                                  guint              position,
@@ -190,6 +245,8 @@ gtk_multi_selection_selection_model_init (GtkSelectionModelInterface *iface)
   iface->unselect_range = gtk_multi_selection_unselect_range;
   iface->select_all = gtk_multi_selection_select_all;
   iface->unselect_all = gtk_multi_selection_unselect_all;
+  iface->select_callback = gtk_multi_selection_select_callback;
+  iface->unselect_callback = gtk_multi_selection_unselect_callback;
   iface->query_range = gtk_multi_selection_query_range;
 }
 
index 8053368c6be84f4e301f1590921f3fd6133fc26f..dfbf167f9a732595a38622fba84ec1f87d5e0654 100644 (file)
@@ -113,6 +113,22 @@ gtk_selection_model_default_unselect_range (GtkSelectionModel *model,
   return FALSE;
 }
 
+static gboolean
+gtk_selection_model_default_select_callback (GtkSelectionModel    *model,
+                                             GtkSelectionCallback  callback,
+                                             gpointer              data)
+{
+  return FALSE;
+}
+
+static gboolean
+gtk_selection_model_default_unselect_callback (GtkSelectionModel    *model,
+                                               GtkSelectionCallback  callback,
+                                               gpointer              data)
+{
+  return FALSE;
+}
+
 static gboolean
 gtk_selection_model_default_select_all (GtkSelectionModel *model)
 {
@@ -142,20 +158,22 @@ gtk_selection_model_default_query_range (GtkSelectionModel *model,
   else
     {
       *n_items = 1;
-      *selected = gtk_selection_model_is_selected (model, position);  
+      *selected = gtk_selection_model_is_selected (model, position);
     }
 }
 
 static void
 gtk_selection_model_default_init (GtkSelectionModelInterface *iface)
 {
-  iface->is_selected = gtk_selection_model_default_is_selected; 
-  iface->select_item = gtk_selection_model_default_select_item; 
-  iface->unselect_item = gtk_selection_model_default_unselect_item; 
-  iface->select_range = gtk_selection_model_default_select_range; 
-  iface->unselect_range = gtk_selection_model_default_unselect_range; 
-  iface->select_all = gtk_selection_model_default_select_all; 
-  iface->unselect_all = gtk_selection_model_default_unselect_all; 
+  iface->is_selected = gtk_selection_model_default_is_selected;
+  iface->select_item = gtk_selection_model_default_select_item;
+  iface->unselect_item = gtk_selection_model_default_unselect_item;
+  iface->select_range = gtk_selection_model_default_select_range;
+  iface->unselect_range = gtk_selection_model_default_unselect_range;
+  iface->select_all = gtk_selection_model_default_select_all;
+  iface->unselect_all = gtk_selection_model_default_unselect_all;
+  iface->select_callback = gtk_selection_model_default_select_callback;
+  iface->unselect_callback = gtk_selection_model_default_unselect_callback;
   iface->query_range = gtk_selection_model_default_query_range;
 
   /**
@@ -324,6 +342,26 @@ gtk_selection_model_unselect_all (GtkSelectionModel *model)
   return iface->unselect_all (model);
 }
 
+gboolean
+gtk_selection_model_select_callback (GtkSelectionModel    *model,
+                                     GtkSelectionCallback  callback,
+                                     gpointer              data)
+{
+  g_return_val_if_fail (GTK_IS_SELECTION_MODEL (model), FALSE);
+
+  return GTK_SELECTION_MODEL_GET_IFACE (model)->select_callback (model, callback, data);
+}
+
+gboolean
+gtk_selection_model_unselect_callback (GtkSelectionModel    *model,
+                                       GtkSelectionCallback  callback,
+                                       gpointer              data)
+{
+  g_return_val_if_fail (GTK_IS_SELECTION_MODEL (model), FALSE);
+
+  return GTK_SELECTION_MODEL_GET_IFACE (model)->unselect_callback (model, callback, data);
+}
+
 /**
  * gtk_selection_model_query_range:
  * @model: a #GtkSelectionModel
index 9e8de6a66b665d3ce6f932e6d092872453804a95..3a73572ac2f1a943faa81626be32b491cecf1960 100644 (file)
 G_BEGIN_DECLS
 
 #define GTK_TYPE_SELECTION_MODEL       (gtk_selection_model_get_type ())
-                                                      
+
 GDK_AVAILABLE_IN_ALL
 G_DECLARE_INTERFACE (GtkSelectionModel, gtk_selection_model, GTK, SELECTION_MODEL, GListModel)
 
+typedef void     (* GtkSelectionCallback) (guint     position,
+                                           guint    *start_range,
+                                           guint    *n_items,
+                                           gboolean *selected,
+                                           gpointer  data);
+
+
 /**
  * GtkSelectionModelInterface:
  * @is_selected: Return if the item at the given position is selected.
@@ -79,6 +86,12 @@ struct _GtkSelectionModelInterface
                                                                  guint                   n_items);
   gboolean              (* select_all)                          (GtkSelectionModel      *model);
   gboolean              (* unselect_all)                        (GtkSelectionModel      *model);
+  gboolean              (* select_callback)                     (GtkSelectionModel      *model,
+                                                                 GtkSelectionCallback    callback,
+                                                                 gpointer                data);
+  gboolean              (* unselect_callback)                   (GtkSelectionModel      *model,
+                                                                 GtkSelectionCallback    callback,
+                                                                 gpointer                data);
   void                  (* query_range)                         (GtkSelectionModel      *model,
                                                                  guint                   position,
                                                                  guint                  *start_range,
@@ -111,6 +124,14 @@ gboolean                gtk_selection_model_select_all          (GtkSelectionMod
 GDK_AVAILABLE_IN_ALL
 gboolean                gtk_selection_model_unselect_all        (GtkSelectionModel      *model);
 
+GDK_AVAILABLE_IN_ALL
+gboolean                gtk_selection_model_select_callback     (GtkSelectionModel      *model,
+                                                                 GtkSelectionCallback    callback,
+                                                                 gpointer                data);
+gboolean                gtk_selection_model_unselect_callback   (GtkSelectionModel      *model,
+                                                                 GtkSelectionCallback    callback,
+                                                                 gpointer                data);
+
 GDK_AVAILABLE_IN_ALL
 void                    gtk_selection_model_query_range         (GtkSelectionModel      *model,
                                                                  guint                   position,